//
//  LLTCustomCamera.swift
//  TakePhoto
//
//  Created by 李陆涛 on 2018/7/23.
//  Copyright © 2018年 llt. All rights reserved.
//

import UIKit

enum CameraStyle {
    
    case none
    case takePhoto
    case clickVideo
    case pressVideo
}

class LLTCustomCamera: UIViewController {
    
    
    @IBOutlet weak var leftTimeLabel: UILabel!
    @IBOutlet weak var progressView: UIProgressView!
    @IBOutlet weak var closeBtn: UIButton!
    
    @IBOutlet weak var takePhotoBtn: LLTTakePhotoBtn!
    
    @IBOutlet weak var selectPhotoStyleCenterX: NSLayoutConstraint!
    @IBOutlet weak var selectPhotoStyleView: UIView!
    @IBOutlet weak var takePhotoStyleBtn: UIButton!
    @IBOutlet weak var clickVideoStyleBtn: UIButton!
    @IBOutlet weak var pressVideoStyleBtn: UIButton!
    
    @IBOutlet weak var containerView: UIView!
    @IBOutlet weak var cameraView: UIView!
    
    @IBOutlet weak var changeCameraBtn: UIButton!
    @IBOutlet weak var changeFlashBtn: UIButton!
    
//    @IBOutlet weak var previewImageView: UIImageView!
    
    private var cameraStyle:CameraStyle = .clickVideo
    
    private var viewmodel:LLTCameraViewModel!
    
    @IBOutlet weak var dotView: UIView!
    
    @IBOutlet weak var progressTop: NSLayoutConstraint!
    
    @IBOutlet weak var selectViewBottom: NSLayoutConstraint!
    
    @IBOutlet weak var topFunView: UIView!
//    @IBOutlet weak var topFunViewH: NSLayoutConstraint!
    @IBOutlet weak var rightFunView: UIView!
    
    @IBOutlet weak var bottomFunView: UIView!
    
    var completeHander:((_ image:UIImage?,_ videoURL:URL?,_ success:Bool) -> Void)?
    
    private var foucsView: UIView!
    
    
    /// 可以选择的功能
    var selectType:SelectType = .all {
        
        didSet {
            
            if selectType == .photo {
                
                cameraStyle = .takePhoto
                
            } else {
                
                cameraStyle = .clickVideo
            }
        }
    }
    
    //    MARK: - 重写系统方法
    override func viewDidLoad() {
        super.viewDidLoad()
        
        LLTPhotoManager.requestCameraAuthority {
            
            [weak self] suc in
            guard let `self` = self else { return }
            
            if !suc {
                
                
                DispatchQueue.main.async {
                    
                    self.completeHander?(nil,nil,false)
                    self.dismiss(animated: true, completion: nil)
                }
                
                return
            }
            
            LLTPhotoManager.requestMicrophoneAuthority {
                
                [weak self] suc in
                guard let `self` = self else { return }
                
                if !suc {
                    
                    
                    DispatchQueue.main.async {
                        
                        self.completeHander?(nil,nil,false)
                        self.dismiss(animated: true, completion: nil)
                    }
                    
                    return
                }
                
                DispatchQueue.main.async {
                
                    self.setupUI()
                }
            }
        }
    }
    
    override var prefersStatusBarHidden: Bool {
        
        return true
    }
    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        
        return .portrait
    }
    //    MARK: - 自定义方法
    
    private func setupUI() {
        
        
        foucsView = UIView(frame: CGRect(origin: CGPoint.zero, size: CGSize(width: 100, height: 100)))
        foucsView.backgroundColor = UIColor.clear
        foucsView.layer.borderWidth = 1.0
        foucsView.layer.borderColor = UIColor.white.cgColor
        foucsView.isHidden = true
        containerView.addSubview(foucsView)
        
        
//        topFunViewH.constant = CGFloat(kNavigationBarHeight)

//        ZLCustomCamera
        
        viewmodel = LLTCameraViewModel()
        
        viewmodel.setupWithPreview(cameraView)
        viewmodel.delegate = self
        viewmodel.maxDuration = (AppManager.share.appModel?.video_time) ?? 15
        
        leftTimeLabel.text = "00:00"
        
        containerView.isUserInteractionEnabled = true
        
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(autoFoucsAction))
        tapGesture.delegate = self
        
        
        containerView.addGestureRecognizer(tapGesture)
        
        
        let zommGesture = UIPinchGestureRecognizer(target: self, action: #selector(pinchAction))
        
        containerView.addGestureRecognizer(zommGesture)
        
        
        changeStyle(cameraStyle)
        takePhotoBtn.delegate = self
        
        NotificationCenter.default.addObserver(self, selector: #selector(becomeActive), name: NSNotification.Name.UIApplicationDidBecomeActive, object: nil)
        
        NotificationCenter.default.addObserver(self, selector: #selector(enterBackground), name: NSNotification.Name.UIApplicationDidEnterBackground, object: nil)
        
        
        if selectType == .photo {
            
            self.clickVideoStyleBtn.isHidden = true
            self.pressVideoStyleBtn.isHidden = true
        } else if selectType == .video {
            
            self.takePhotoStyleBtn.isHidden = true
            
        }
        
    }
    
    @objc private func enterBackground() {
        
        viewmodel.stopRecording()
        
    }
    
    @objc private func becomeActive() {
        
        viewmodel.startRunning()
        
    }
    
    
    deinit {
        
        NotificationCenter.default.removeObserver(self)
    }
    
    
    private var lastScale: CGFloat = 1.0
    
    //    -------------------------捏合手势-------------------------
    @objc private func pinchAction(_ gesture:UIPinchGestureRecognizer) {
        
        
        if gesture.state == .began {
            lastScale = 1.0
        }
        
        if gesture.state == .changed {
            
            let scale = gesture.scale
            
            var zoom = viewmodel.zoomFactor ?? 1.0
            
            zoom = zoom + (scale - lastScale)
            
            viewmodel.zoomFactor = zoom
            
            lastScale = scale
            
        }
    }
    
    //    -------------------------点击对焦-------------------------
    @objc private func autoFoucsAction(_ gesture:UITapGestureRecognizer) {
        
        let point = gesture.location(in: containerView)
        
        showSquareBox(point)
        
        viewmodel.foucsAction(point)
    }
    //    -------------------------对焦动画-------------------------
    private func showSquareBox(_ point: CGPoint) {
        
        
        foucsView.isHidden = false
        foucsView.center = point
        
        let animation = CABasicAnimation(keyPath: "transform.scale")
        animation.toValue = 1.2
        animation.autoreverses = true
        animation.duration = 1.0
        
        foucsView.layer.add(animation, forKey: "transform.scale")
        
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1.5) {
            
            [weak self] in
            guard let `self` = self else { return }
            
            if point.equalTo(self.foucsView.center) {
                
                self.foucsView.isHidden = true
            }
        }
    }
    //    -------------------------切换摄像头-------------------------
    @IBAction private func changeCameraAction(_ sender: UIButton) {
        
        let (position,success) = viewmodel.changeCameraPositionAction()
        
        if !success {
            return
        }
        
        viewmodel.changeFlashMode(.off)
        viewmodel.changeTorchMode(.off)
        
        let animation = CATransition()
        animation.duration = 0.25
        animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
        animation.type = "fade"
        if position == .back {
            changeFlashBtn.isHidden = false
            animation.subtype = kCATransitionFromLeft
        } else {
            changeFlashBtn.isHidden = true
            animation.subtype = kCATransitionFromRight
        }
        cameraView.layer.add(animation, forKey: nil)
    }
    //    -------------------------切换闪光灯-------------------------
    @IBAction private func chnageFlashAction(_ sender: UIButton) {
        
    
        if cameraStyle == .takePhoto {
            
            viewmodel.changeFlashMode()
        } else {
            
            viewmodel.changeTorchMode()
        }
    }
    
    @IBAction private func closeAction(_ sender: UIButton) {
        
        viewmodel.stopRunning()
        self.completeHander?(nil,nil,false)
        self.dismiss(animated: true, completion: nil)
        
    }
    
    
    @IBAction private func changePhotoStyle(_ sender: UIButton) {
        
        viewmodel.changeFlashMode(.off)
        viewmodel.changeTorchMode(.off)
        
        if sender == clickVideoStyleBtn {
            
            if selectType == .photo {
                
                showToast("只能选择图片")
                return
            }
            
            changeStyle(.clickVideo)
            
        } else if sender == pressVideoStyleBtn {
            
            if selectType == .photo {
                
                showToast("只能选择图片")
                return
            }
            changeStyle(.pressVideo)
        } else {
            
            if selectType == .video {
                
                showToast("只能选择视频")
                return
            }
            
            changeStyle(.takePhoto)
        }
        
    }
    
    private func changeStyle(_ style:CameraStyle) {
        
        cameraStyle = style
        
        let width = selectPhotoStyleView.frame.size.width / 3.0
        
        if style == .clickVideo {
            
            selectPhotoStyleCenterX.constant = 0
            
            progressTop.constant = 8
            
        } else if style == .pressVideo {
            
            selectPhotoStyleCenterX.constant = -width
            progressTop.constant = 8
        } else {

            selectPhotoStyleCenterX.constant = width
            
            progressTop.constant = -20
        }
        takePhotoBtn.changeStyle(cameraStyle)
        
        UIView.animate(withDuration: 0.25) {
            
            [weak self] in
            guard let `self` = self else { return }
            
            self.view.layoutIfNeeded()
        }
    }
}

extension LLTCustomCamera: LLTTakePhotoBtnDelegate {
    
    func startRecordingDelegate(_ sender: LLTTakePhotoBtn) {
        
        viewmodel.startRecording()
        
        
        self.selectViewBottom.constant = -58
        self.dotView.isHidden = true
        
        UIView.animate(withDuration: 0.25) {
            
            [weak self] in
            guard let `self` = self else { return }
            
            self.view.layoutIfNeeded()
        }
        
    }
    func stopRecordingDelegate(_ sender: LLTTakePhotoBtn) {
        
        viewmodel.stopRecording()
        
        self.selectViewBottom.constant = -8
        self.dotView.isHidden = false
        
        UIView.animate(withDuration: 0.25) {
            
            [weak self] in
            guard let `self` = self else { return }
            
            self.view.layoutIfNeeded()
        }
        
    }
    func takePhotoDelegate(_ sender: LLTTakePhotoBtn) {
        
        viewmodel.takePhoto()
    }
    
    func videoZoomFactor(_ zoom:CGFloat) {
        
        viewmodel.zoomFactor = zoom
    }
    
}

extension LLTCustomCamera : LLTCameraViewModelDelegate {
    
    
    func flashModel(_ model: FlashModel) {
        
        var image :UIImage? = nil
        switch model {
        case .off:
            image = #imageLiteral(resourceName: "flash_off")
            break
        case .on:
            image = #imageLiteral(resourceName: "flash_on")
            break
        }
        changeFlashBtn.setImage(image, for: .normal)
    }
    
    
    
    func takePhtotFinish(image:UIImage?,error:ErrorType?) {
        
//        self.completeHander?(image,nil,error.msg)
        
        guard let image = image else {
            
            self.completeHander?(nil,nil,false)
            return
        }
        
        self.completeHander?(image,nil,true)
    }
    
    func videoRecordStart() {
        
        
    }
    
    func videoRecordFinish(videourl: URL?, error: ErrorType?) {
        
        
        takePhotoBtn.forceStopRecording()
        
        
        guard let url = videourl else {
            
            self.completeHander?(nil,nil,false)
            
            return
        }
        
        if (self.progressView.progress * viewmodel.maxDuration) < 3 {
            
            self.showToast("录制时间过短")
            
            UIView.animate(withDuration: 0.25) {
                [weak self] in
                guard let `self` = self else { return }
                
                self.progressView.progress = 0
                
            }
            
            return
        }
        
        
        self.completeHander?(nil,url,true)
        
    }
    
    func videoRecordTime(time: Float,progress:Float) {
        
        progressView.progress = progress
        leftTimeLabel.text = String(format: "00:%02.0f", time)
    }
}

extension LLTCustomCamera : UIGestureRecognizerDelegate {
    
    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        
        let location = gestureRecognizer.location(ofTouch: 0, in: bottomFunView)
        
        if takePhotoBtn.frame.contains(location) {
            
            return false
        }
        
        return true
    }
}
